#include "device.h"
#include "component.h"
#include "radardrv.h"

#define DSENSOR_LOG(format, ...) OSAL_LOG(C_BLUE format C_NONE, ##__VA_ARGS__)
#define __DSENSOR_LOG(format, ...) __OSAL_LOG(C_BLUE format C_NONE, ##__VA_ARGS__)

#define VHW_IRQ_SENSOR vPIN_I12

typedef struct
{
    Dsensor_Sensitivity_enum_t cfi;
    uint8_t reserved[14];
} Dsensor_Cfg_stu_t;

__EFRAM static FunctionalState sensor_swi = DISABLE;
__EFRAM static Dsensor_Sensitivity_enum_t sensor_sensitivity = DSENSOR_SENS_H;
static DsensorMsg_t dsensor_msg = {0};
const uint16_t sensor_threshold[3] = {200, 400, 600};

/**
  * @brief  传感器中断处理
  * @note   只创建中断事件，任务里面处理
  * @return SUCCESS/ERROR
  */
static void dsensor_irqHandle(char *name, uint8_t status, uint8_t times)
{
    if (status == INPUT_PORT_STA_PRESS)
    {
        OSAL_EventCreateFromISR(COMP_DSENSOR);
    }
}

/**
  * @brief  传感器初始化
  * @note   
  */
static void dsensor_init(void)
{
    static uint8_t init_flag = 0;
    if (init_flag == 0)
    {
        init_flag = 1;

        InputPort_stu_t port[] = 
        {
            {"DSENSOR_INT", VHW_IRQ_SENSOR, INPUT_PORT_LOGIC_HIGH, INPUT_PORT_FUNC_SINGLE}, //中断脚
        };
        /* 注册端口 */
        InputPort_Registered(port, OSAL_LENGTH(port), dsensor_irqHandle);
        OSAL_NvRead(0, &sensor_sensitivity, sizeof(sensor_sensitivity));
        if (!(sensor_sensitivity >= DSENSOR_SENS_H && sensor_sensitivity <= DSENSOR_SENS_OFF))
        {
            sensor_sensitivity = DSENSOR_SENS_H;
        }
        
        Radar_Init(sensor_threshold[sensor_sensitivity - 1]);
        if (sensor_sensitivity == DSENSOR_SENS_OFF || sensor_swi == DISABLE)
        {
            Radar_Sleep();
            InputPort_DisableProt("DSENSOR_INT");
        }
        else
        {
            Radar_Wake();
            InputPort_EnableProt("DSENSOR_INT");
        }
    }
}

/**
  * @brief  传感器使能控制
  * @note
  * @return SUCCESS/ERROR
  */
static ErrorStatus dsensor_power_ctrl(FunctionalState ctrl)
{
    __DSENSOR_LOG("dsensor_power_ctrl(%d)\r\n", ctrl);
    if (ctrl == DISABLE)
    {
        sensor_swi = ctrl;
        Radar_Sleep();
        InputPort_DisableProt("DSENSOR_INT");
    }
    else
    {
        if(sensor_sensitivity == DSENSOR_SENS_OFF)
        {
            __DSENSOR_LOG("dsensor power on fail\r\n");
        }
        else
        {
            sensor_swi = ctrl;
            Radar_Wake();
            InputPort_EnableProt("DSENSOR_INT");
        }
    }
    return SUCCESS;
}

/**
  * @brief  设置传感器灵敏度
  * @note
  * @return SUCCESS/ERROR
  */
static ErrorStatus dsensor_set_sensitivity(Dsensor_Sensitivity_enum_t val)
{
    __DSENSOR_LOG("dsensor_set_sensitivity(%d)\r\n", val);
    if(val >= DSENSOR_SENS_H && val <= DSENSOR_SENS_OFF)
    {
        if (val == DSENSOR_SENS_OFF)
        {
            dsensor_power_ctrl(DISABLE);
        }
        else
        {
            Radar_SetThreshold(sensor_threshold[val - 1]);
            if (sensor_sensitivity == DSENSOR_SENS_OFF)
            {
                dsensor_power_ctrl(ENABLE);
            }
        }
        sensor_sensitivity = val;
        return OSAL_NvWrite(OSAL_OFFSET(Dsensor_Cfg_stu_t, cfi), &sensor_sensitivity, sizeof(sensor_sensitivity));
    }
    return ERROR;
}

/**
  * @brief  获取传感器灵敏度
  * @note
  * @return SUCCESS/ERROR
  */
static Dsensor_Sensitivity_enum_t dsensor_get_sensitivity(void)
{
    __DSENSOR_LOG("dsensor_get_sensitivity(%d)\r\n", sensor_sensitivity);
    return sensor_sensitivity;
}

/**
  * @brief  传感器休眠中断唤醒回调
  * @note
  * @return int32_t
  */
static int32_t Dsensor_WakeupHandle(uint32_t dev)
{
    return 1;
}
COMPONENT_WAKEUP_EXPORT(COMP_DSENSOR, Dsensor_WakeupHandle, VHW_IRQ_SENSOR);

/**
  * @brief  雷达传感器任务函数
  *
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t Dsensor_Task(uint32_t event)
{
    /* 系统启动事件 */
    if (event & EVENT_SYS_START)
    {
        dsensor_init();
        SYS_API(dsensor_power_ctrl);
        SYS_API(dsensor_set_sensitivity);
        SYS_API(dsensor_get_sensitivity);
        return (event ^ EVENT_SYS_START);
    }

    /* 系统休眠事件 */
    if (event & EVENT_SYS_SLEEP)
    {
        return (event ^ EVENT_SYS_SLEEP);
    }

    if (event & EVENT_SYS_ISR)
    {
        dsensor_msg.type = READ_DISTANCE;
        dsensor_msg.ps_msg.action = USER_ACTION_PRESS;
        OSAL_MessagePublish(&dsensor_msg, sizeof(DsensorMsg_t));

        return (event ^ EVENT_SYS_ISR);
    }

    return 0;
}
COMPONENT_TASK_EXPORT(COMP_DSENSOR, Dsensor_Task, sizeof(Dsensor_Cfg_stu_t));
